//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  http://www.nopCommerce.com/License.aspx. 
// 
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
// See the License for the specific language governing rights and limitations under the License.
// 
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
// 
// Contributor(s): _______. 
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using Tathata.Common.Caching;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;
using System.Data;
using System.Globalization;
using Tathata.Common.DAL;
using Tathata.Common.BLL.Entities;
using Tathata.Common.BLL.EntityCollections;
using Tathata.Common.DAL.Managers;

namespace Tathata.Common.BLL.Managers
{
    /// <summary>
    /// Product variant manager
    /// </summary>
    public class ProductVariantManager
    {
        #region Constants
        private const string PRODUCTVARIANTS_ALL_KEY = "Nop.productvariant.all-{0}-{1}";
        private const string PRODUCTVARIANTS_BY_ID_KEY = "Nop.productvariant.id-{0}";
        #endregion

        #region Methods
        /// <summary>
        /// Marks a product variant as deleted
        /// </summary>
        /// <param name="ProductVariantID">Product variant identifier</param>
        public static void MarkProductVariantAsDeleted(int ProductVariantID)
        {
            ProductVariant productVariant = GetByProductVariantID(ProductVariantID);
            if (productVariant != null)
            {
                UpdateProductVariant(productVariant.ProductVariantID, productVariant.ProductID, productVariant.Name,
                    productVariant.SKU, productVariant.Description, productVariant.AdminComment, productVariant.ManufacturerPartNumber,
                    productVariant.IsDownload, productVariant.DownloadID, productVariant.IsShipEnabled,
                    productVariant.IsFreeShipping, productVariant.TaxCategoryID, productVariant.StockQuantity,
                    productVariant.WarehouseId, productVariant.DisableBuyButton, productVariant.RequiresTextOption, productVariant.TextOptionPrompt,
                    productVariant.Price, productVariant.OldPrice,
                    productVariant.Weight, productVariant.Length, productVariant.Width, productVariant.Height, productVariant.PictureID,
                    productVariant.Published, true, productVariant.DisplayOrder, productVariant.CreatedOn, productVariant.UpdatedOn);
            }

            if (NopContext.IsCachable)
            {
                NopCache.RemoveByPattern(PRODUCTVARIANTS_ALL_KEY);
                NopCache.RemoveByPattern(PRODUCTVARIANTS_BY_ID_KEY);
            }
        }

        /// <summary>
        /// Adjusts inventory
        /// </summary>
        /// <param name="ProductVariantID">Product variant identifier</param>
        /// <param name="decrease">A value indicating whether to increase or descrease product variant stock quantity</param>
        /// <param name="Quantity">Quantity</param>
        public static void AdjustInventory(int ProductVariantID, bool decrease, int Quantity)
        {
            ProductVariant productVariant = GetByProductVariantID(ProductVariantID);
            if (productVariant == null)
                return;
            int NewStockQuantity = 0;
            if (decrease)
                NewStockQuantity = productVariant.StockQuantity - Quantity;
            else
                NewStockQuantity = productVariant.StockQuantity + Quantity;
            if (productVariant != null)
            {
                UpdateProductVariant(productVariant.ProductVariantID, productVariant.ProductID, productVariant.Name,
                    productVariant.SKU, productVariant.Description, productVariant.AdminComment, productVariant.ManufacturerPartNumber,
                    productVariant.IsDownload, productVariant.DownloadID, productVariant.IsShipEnabled,
                    productVariant.IsFreeShipping, productVariant.TaxCategoryID, NewStockQuantity,
                    productVariant.WarehouseId, productVariant.DisableBuyButton, productVariant.RequiresTextOption, productVariant.TextOptionPrompt,
                    productVariant.Price, productVariant.OldPrice,
                    productVariant.Weight, productVariant.Length, productVariant.Width, productVariant.Height, productVariant.PictureID,
                    productVariant.Published, productVariant.Deleted, productVariant.DisplayOrder, productVariant.CreatedOn, productVariant.UpdatedOn);
            }

            if (NopContext.IsCachable)
            {
                NopCache.RemoveByPattern(PRODUCTVARIANTS_ALL_KEY);
                NopCache.RemoveByPattern(PRODUCTVARIANTS_BY_ID_KEY);
            }
        }

        /// <summary>
        /// Remove a product variant picture
        /// </summary>
        /// <param name="ProductVariantID">Product variant identifier</param>
        public static void RemoveProductVariantPicture(int ProductVariantID)
        {
            ProductVariant productVariant = GetByProductVariantID(ProductVariantID);
            if (productVariant != null)
            {
                UpdateProductVariant(productVariant.ProductVariantID, productVariant.ProductID, productVariant.Name,
                    productVariant.SKU, productVariant.Description, productVariant.AdminComment, productVariant.ManufacturerPartNumber,
                    productVariant.IsDownload, productVariant.DownloadID, productVariant.IsShipEnabled, productVariant.IsFreeShipping,
                    productVariant.TaxCategoryID, productVariant.StockQuantity,
                    productVariant.WarehouseId, productVariant.DisableBuyButton, productVariant.RequiresTextOption, productVariant.TextOptionPrompt,
                    productVariant.Price, productVariant.OldPrice,
                    productVariant.Weight, productVariant.Length, productVariant.Width, productVariant.Height, 0,
                    productVariant.Published, productVariant.Deleted, productVariant.DisplayOrder, productVariant.CreatedOn, productVariant.UpdatedOn);
            }

            if (NopContext.IsCachable)
            {
                bool showHidden = NopContext.Current.IsAdmin;
                NopCache.RemoveByPattern(PRODUCTVARIANTS_ALL_KEY);
                NopCache.RemoveByPattern(PRODUCTVARIANTS_BY_ID_KEY);
            }
        }

        /// <summary>
        /// Remove a product variant download
        /// </summary>
        /// <param name="ProductVariantID">Product variant identifier</param>
        public static void RemoveProductVariantDownload(int ProductVariantID)
        {
            ProductVariant productVariant = GetByProductVariantID(ProductVariantID);
            if (productVariant != null)
            {
                UpdateProductVariant(productVariant.ProductVariantID, productVariant.ProductID, productVariant.Name,
                    productVariant.SKU, productVariant.Description, productVariant.AdminComment, productVariant.ManufacturerPartNumber,
                    productVariant.IsDownload, 0, productVariant.IsShipEnabled, productVariant.IsFreeShipping,
                    productVariant.TaxCategoryID, productVariant.StockQuantity,
                    productVariant.WarehouseId, productVariant.DisableBuyButton, productVariant.RequiresTextOption, productVariant.TextOptionPrompt,
                    productVariant.Price, productVariant.OldPrice,
                    productVariant.Weight, productVariant.Length, productVariant.Width, productVariant.Height, productVariant.PictureID,
                    productVariant.Published, productVariant.Deleted, productVariant.DisplayOrder, productVariant.CreatedOn, productVariant.UpdatedOn);
            }

            if (NopContext.IsCachable)
            {
                bool showHidden = NopContext.Current.IsAdmin;
                NopCache.RemoveByPattern(PRODUCTVARIANTS_ALL_KEY);
                NopCache.RemoveByPattern(PRODUCTVARIANTS_BY_ID_KEY);
            }
        }

        /// <summary>
        /// Gets a product variant
        /// </summary>
        /// <param name="ProductVariantID">Product variant identifier</param>
        /// <returns>Product variant</returns>
        public static ProductVariant GetByProductVariantID(int ProductVariantID)
        {
            string key = string.Format(PRODUCTVARIANTS_BY_ID_KEY, ProductVariantID);
            object obj2 = NopCache.Get(key);
            if (NopContext.IsCachable && (obj2 != null))
            {
                return (ProductVariant)obj2;
            }

            ProductVariant productVariant = ProductVariantDBManager.GetByProductVariantID(ProductVariantID);

            if (NopContext.IsCachable)
            {
                NopCache.Max(key, productVariant);
            }
            return productVariant;
        }

        /// <summary>
        /// Inserts a product variant
        /// </summary>
        /// <param name="ProductID">The product identifier</param>
        /// <param name="Name">The name</param>
        /// <param name="SKU">The SKU</param>
        /// <param name="Description">The description</param>
        /// <param name="AdminComment">The admin comment</param>
        /// <param name="ManufacturerPartNumber">The manufacturer part number</param>
        /// <param name="IsDownload">A value indicating whether the product variant is download</param>
        /// <param name="DownloadID">The download identifier</param>
        /// <param name="IsShipEnabled">A value indicating whether the entity is ship enabled</param>
        /// <param name="IsFreeShipping">A value indicating whether the entity is free shipping</param>
        /// <param name="TaxCategoryID">The tax category identifier</param>
        /// <param name="StockQuantity">The stock quantity</param>
        /// <param name="WarehouseId">The warehouse identifier</param>
        /// <param name="DisableBuyButton">A value indicating whether to disable buy button</param>
        /// <param name="RequiresTextOption">A value indicating whether the entity requires text option</param>
        /// <param name="TextOptionPrompt">The text option prompt</param>
        /// <param name="Price">The price</param>
        /// <param name="OldPrice">The old price</param>
        /// <param name="Weight">The weight</param>
        /// <param name="Length">The length</param>
        /// <param name="Width">The width</param>
        /// <param name="Height">The height</param>
        /// <param name="PictureID">The picture identifier</param>
        /// <param name="Published">A value indicating whether the entity is published</param>
        /// <param name="Deleted">A value indicating whether the entity has been deleted</param>
        /// <param name="DisplayOrder">The display order</param>
        /// <param name="CreatedOn">The date and time of instance creation</param>
        /// <param name="UpdatedOn">The date and time of instance update</param>
        /// <returns>Product variant</returns>
        public static ProductVariant InsertProductVariant(int ProductID, string Name, string SKU, string Description, string AdminComment,
            string ManufacturerPartNumber, bool IsDownload, int DownloadID, bool IsShipEnabled,
            bool IsFreeShipping, int TaxCategoryID, int StockQuantity,
            int WarehouseId, bool DisableBuyButton, bool RequiresTextOption, string TextOptionPrompt, decimal Price, decimal OldPrice,
            decimal Weight, decimal Length, decimal Width, decimal Height, int PictureID,
           bool Published, bool Deleted, int DisplayOrder, DateTime CreatedOn, DateTime UpdatedOn)
        {
            ProductVariant productVariant = ProductVariantDBManager.InsertProductVariant(ProductID, Name, SKU, Description, AdminComment,
             ManufacturerPartNumber, IsDownload, DownloadID, IsShipEnabled,
             IsFreeShipping, TaxCategoryID, StockQuantity,
             WarehouseId,DisableBuyButton, RequiresTextOption, TextOptionPrompt, Price, OldPrice,
             Weight, Length, Width, Height, PictureID,
            Published, Deleted, DisplayOrder, CreatedOn, UpdatedOn);

            if (NopContext.IsCachable)
            {
                NopCache.RemoveByPattern(PRODUCTVARIANTS_ALL_KEY);
                NopCache.RemoveByPattern(PRODUCTVARIANTS_BY_ID_KEY);
            }

            return productVariant;
        }
        
        /// <summary>
        /// Updates the product variant
        /// </summary>
        /// <param name="ProductVariantID">The product variant identifier</param>
        /// <param name="ProductID">The product identifier</param>
        /// <param name="Name">The name</param>
        /// <param name="SKU">The SKU</param>
        /// <param name="Description">The description</param>
        /// <param name="AdminComment">The admin comment</param>
        /// <param name="ManufacturerPartNumber">The manufacturer part number</param>
        /// <param name="IsDownload">A value indicating whether the product variant is download</param>
        /// <param name="DownloadID">The download identifier</param>
        /// <param name="IsShipEnabled">A value indicating whether the entity is ship enabled</param>
        /// <param name="IsFreeShipping">A value indicating whether the entity is free shipping</param>
        /// <param name="TaxCategoryID">The tax category identifier</param>
        /// <param name="StockQuantity">The stock quantity</param>
        /// <param name="WarehouseId">The warehouse identifier</param>
        /// <param name="DisableBuyButton">A value indicating whether to disable buy button</param>
        /// <param name="RequiresTextOption">A value indicating whether the entity requires text option</param>
        /// <param name="TextOptionPrompt">The text option prompt</param>
        /// <param name="Price">The price</param>
        /// <param name="OldPrice">The old price</param>
        /// <param name="Weight">The weight</param>
        /// <param name="Length">The length</param>
        /// <param name="Width">The width</param>
        /// <param name="Height">The height</param>
        /// <param name="PictureID">The picture identifier</param>
        /// <param name="Published">A value indicating whether the entity is published</param>
        /// <param name="Deleted">A value indicating whether the entity has been deleted</param>
        /// <param name="DisplayOrder">The display order</param>
        /// <param name="CreatedOn">The date and time of instance creation</param>
        /// <param name="UpdatedOn">The date and time of instance update</param>
        /// <returns>Product variant</returns>
        public static ProductVariant UpdateProductVariant(int ProductVariantID, int ProductID, string Name, string SKU, string Description, string AdminComment,
            string ManufacturerPartNumber, bool IsDownload, int DownloadID, bool IsShipEnabled,
            bool IsFreeShipping, int TaxCategoryID, int StockQuantity,
            int WarehouseId, bool DisableBuyButton, bool RequiresTextOption, string TextOptionPrompt, decimal Price, decimal OldPrice,
             decimal Weight, decimal Length, decimal Width, decimal Height, int PictureID,
           bool Published, bool Deleted, int DisplayOrder, DateTime CreatedOn, DateTime UpdatedOn)
        {
            ProductVariant productVariant = ProductVariantDBManager.UpdateProductVariant(ProductVariantID, ProductID, Name, SKU, Description, AdminComment,
             ManufacturerPartNumber, IsDownload, DownloadID, IsShipEnabled,
             IsFreeShipping, TaxCategoryID, StockQuantity,
             WarehouseId,DisableBuyButton, RequiresTextOption, TextOptionPrompt, Price, OldPrice,
             Weight, Length, Width, Height, PictureID,
             Published, Deleted, DisplayOrder, CreatedOn, UpdatedOn);

            if (NopContext.IsCachable)
            {
                NopCache.RemoveByPattern(PRODUCTVARIANTS_ALL_KEY);
                NopCache.RemoveByPattern(PRODUCTVARIANTS_BY_ID_KEY);
            }

            return productVariant;
        }

        /// <summary>
        /// Gets product variants by product identifier
        /// </summary>
        /// <param name="ProductID">The product identifier</param>
        /// <returns>Product variant collection</returns>
        public static ProductVariantCollection GetByProductVariantsByProductID(int ProductID)
        {
            bool showHidden = NopContext.Current.IsAdmin;
            return GetByProductVariantsByProductID(ProductID, showHidden);
        }

        /// <summary>
        /// Gets product variants by product identifier
        /// </summary>
        /// <param name="ProductID">The product identifier</param>
        /// <param name="showHidden">A value indicating whether to show hidden records</param>
        /// <returns>Product variant collection</returns>
        public static ProductVariantCollection GetByProductVariantsByProductID(int ProductID, bool showHidden)
        {
            string key = string.Format(PRODUCTVARIANTS_ALL_KEY, showHidden, ProductID);
            object obj2 = NopCache.Get(key);
            if (NopContext.IsCachable && (obj2 != null))
            {
                return (ProductVariantCollection)obj2;
            }

            ProductVariantCollection productVariantCollection = ProductVariantDBManager.GetByProductVariantsByProductID(ProductID, showHidden);
            if (NopContext.IsCachable)
            {
                NopCache.Max(key, productVariantCollection);
            }
            return productVariantCollection;
        }
        #endregion
    }
}
